package com.szj.father.java8;

import org.junit.Test;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;

public class CompletableFutureTests2 {

    /**
     * thenApply 表示某个任务执行完成后执行的动作，即回调方法，会将该任务的执行结果即方法返回值作为入参传递到回调方法中
     * thenApplyAsync与thenApply的区别在于:
     * 前者是将job2提交到线程池中异步执行，实际执行job2的线程可能是另外一个线程，
     * 后者是由执行job1的线程立即执行job2，即两个job都是同一个线程执行的。
     *
     * @throws Exception
     */
    @Test
    public void test5() throws Exception {
        ForkJoinPool pool = new ForkJoinPool();
        // 创建异步执行任务:
        CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
            System.out.println("1 start");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("1 end");
            return 1.2;
        }, pool);
        // cf关联的异步任务的返回值作为方法入参，传入到thenApply的方法中
        // thenApply这里实际创建了一个新的CompletableFuture实例
        CompletableFuture<String> cf2 = cf.thenApply((result) -> {
            System.out.println("2 start");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("2 end");
            return "test:" + result;
        });
        // 等待子任务执行完成 s
        System.out.println("run result->" + cf.get());
        System.out.println("run result->" + cf2.get());
    }


    /**
     * thenAccept 同 thenApply 接收上一个任务的返回值作为参数，但是无返回值；
     * thenRun 的方法没有入参
     */
    @Test
    public void test6() throws Exception {
        ForkJoinPool pool = new ForkJoinPool();
        // 创建异步执行任务:
        CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
            return 1.2;
        }, pool);

        CompletableFuture cf2 = cf.thenApply((result) -> {
            return "test:" + result;
        }).thenAccept((result) -> { //接收上一个任务的执行结果作为入参，但是没有返回值
            System.out.println(result);
        }).thenRun(() -> { //无入参，也没有返回值
            System.out.println("thenRun do something");
        });
        System.out.println("run result->" + cf.get());
        System.out.println("run result->" + cf2.get());
    }


}
